# VideoCacheInotifyHandler - Update cache according to file system changes.
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import os
from pyinotify import ProcessEvent
from backend.components.mediacache.video_cache import VideoCache

class VideoCacheInotifyHandler(ProcessEvent):
    """
    Update cache according to file system changes.'
    
    Object from this class handles inotify events for video cache.
    
    NOTE: VideoCache object is created in every method, because of SQLite
          doesn't allow cursor to be used in separate threads.
    """
    
    # Logger object
    __logger = None
    
    # Configuration object
    __configuration = None
    
    # File System Observer object
    __fs_observer = None

    def __init__(self, logger, configuration, fs_observer):
        """
        Create a new VideoCacheInotifyHandler object, which handles file system
        changes. In other words, object from this class makes sure that cache is
        always up-to-date.
        """
        self.__logger = logger
        self.__configuration = configuration
        self.__fs_observer = fs_observer
        
    def process_IN_DELETE(self, event):
        """
        File deleted
        """
        print '%s: DELETED' % os.path.join(event.path, event.name)
        video_cache = VideoCache(self.__logger, self.__configuration)
        
        # File deleted - Remove file from cache
        if video_cache.isSupportedFormat(event.name):
            video_cache.removeFile(os.path.join(event.path, event.name))
        else:
            # Directory deleted - Remove directory from cache
            if video_cache.isDirectoryInCache(os.path.join(event.path, event.name)):
                self.__fs_observer.removeFolder(os.path.join(event.path, event.name))
                video_cache.removeDirectory(os.path.join(event.path, event.name))

    def process_IN_CREATE(self, event):
        """
        File created
        """
        print '%s: CREATED' % os.path.join(event.path, event.name)
        video_cache = VideoCache(self.__logger, self.__configuration)

        # Directory created - Add directory to cache
        if os.path.isdir(os.path.join(event.path, event.name)): 
            self.__fs_observer.addFolder(os.path.join(event.path, event.name), "video")
            video_cache.addDirectory(os.path.join(event.path, event.name))
            
        # File created - Add file to cache
        else:
            if video_cache.isSupportedFormat(event.name):
                video_cache.addFile(os.path.join(event.path, event.name))
        
    def process_IN_MODIFY(self, event):
        """
        File or directory was modified.
        """
        print '%s: MODIFIED' % os.path.join(event.path, event.name)
        video_cache = VideoCache(self.__logger, self.__configuration)
        
        # Directory created - Add directory to cache
        if os.path.isdir(os.path.join(event.path, event.name)): 
            self.__fs_observer.addFolder(os.path.join(event.path, event.name), "video")
            video_cache.updateDirectory(os.path.join(event.path, event.name))
            
        # File created - Add file to cache
        else:
            if video_cache.isSupportedFormat(event.name):
                video_cache.updateFile(os.path.join(event.path, event.name))
        
    def process_IN_MOVED_FROM(self, event):
        """
        File or directory is moved from observed. (same as delete in our point of view)
        """
        print '%s: IN_MOVED_FROM' % os.path.join(event.path, event.name)
        video_cache = VideoCache(self.__logger, self.__configuration)
        self.process_IN_DELETE(event)
    
    def process_IN_MOVED_TO(self, event):
        """
        File or directory is moved in to observed. (same as create in our point of view)
        """
        print '%s: IN_MOVED_TO' % os.path.join(event.path, event.name)
        self.process_IN_CREATE(event)
        
    def process_IN_MOVE_SELF(self, event):
        """
        
        """
        print '%s: IN_MOVE_SELF' % os.path.join(event.path, event.name)
    
    def process_IN_DELETE_SELF(self, event):
        """
        Listened directory was deleted
        """
        print '%s: observed deleted' % os.path.join(event.path, event.name)
        video_cache = VideoCache(self.__logger, self.__configuration)
        if video_cache.isDirectoryInCache(os.path.join(event.path, event.name)):
            video_cache.removeDirectory(os.path.join(event.path, event.name))
            self.__fs_observer.removeFolder(os.path.join(event.path, event.name))
    
    def process_default(self, event):
        """
        Ultimately, this method is called for all others kind of events.
        """
        pass
